package com.feidee.data.report.dao.impl;

import com.feidee.data.report.constant.Constant;
import com.feidee.data.report.dao.IImpalaDao;
import com.feidee.data.report.exception.DataDaoException;
import com.feidee.data.report.util.DbOperationUtil;
import com.feidee.data.report.util.JdbcManager;
import com.feidee.data.report.util.ToolUtils;
import com.feidee.fdcommon.configuration.CustomConfiguration;
import org.apache.log4j.Logger;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ImpalaDaoImpl extends BaseReportQueryDao implements IImpalaDao {

	private static Logger logger = Logger.getLogger(ImpalaDaoImpl.class);

	@Override
	public void setup() {
		super.setup();
	}

	@Override
	public void cleanup() {
		super.cleanup();
	}

	public void setConfigurtion() {
		engineFlag = Constant.IMPALA_ENG;

		driverStr = CustomConfiguration.getString("impala.jdbc.driver");
		if (!ToolUtils.isNotNull(driverStr)) {
			driverStr = Constant.IMPALA_DRIVER;
		}

		urlStr = CustomConfiguration.getString("impala.jdbc.url");
		if (!ToolUtils.isNotNull(urlStr)) {
			urlStr = Constant.IMPALA_CONNECTION;
		}

		usernameStr = CustomConfiguration.getString("impala.jdbc.username");
		if (!ToolUtils.isNotNull(usernameStr)) {
			usernameStr = Constant.IMPALA_USER;
		}

		passwordStr = CustomConfiguration.getString("impala.jdbc.password");
		if (!ToolUtils.isNotNull(passwordStr)) {
			passwordStr = Constant.IMPALA_PWD;
		}
	}

	@Override
	public List<String> showTables(String dbName) throws DataDaoException {

		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		List<String> list = new ArrayList<String>();

		try {
			con = JdbcManager.getConnection(driverStr, urlStr, usernameStr, passwordStr);
			stmt = con.createStatement();
			stmt.execute("USE " + dbName);
			rs = stmt.executeQuery("SHOW TABLES");
			while (rs.next()) {
				String name = rs.getString(1);
				list.add(name);
			}
		} catch (Exception e) {
			logger.error("RUN IMPALA SQL SHOW TABLES ERROR", e);
			throw new DataDaoException(e.getMessage(), e);
		} finally {
			DbOperationUtil.cleanConnEnv(con, stmt, rs);
		}
		return list;
	}

	@Override
	public List<Map<String, Object>> query(String sql) throws DataDaoException {
		Connection con = null;
		Statement stmt = null;
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			con = JdbcManager.getConnection(driverStr, urlStr, usernameStr, passwordStr);
			stmt = con.createStatement();
			ResultSet rs = null;
			try {
				rs = stmt.executeQuery(sql);
				ResultSetMetaData rsm = rs.getMetaData();
				String[] colN = new String[rsm.getColumnCount()];
				for (int i = 0; i < rsm.getColumnCount(); i++) {
					colN[i] = rsm.getColumnName(i + 1);
				}

				while (rs.next()) {
					Map<String, Object> map = new HashMap<String, Object>();
					for (int i = 0; i < colN.length; i++) {
						map.put(colN[i], rs.getString(colN[i]));
					}
					list.add(map);
				}
			} catch (Exception e) {
				throw new Exception(e);
			} finally {
				if (rs != null)
					rs.close();
				stmt.close();
				con.close();
			}
		} catch (Exception e) {
			logger.error("RUN IMPALA SQL SHOW TABLES ERROR", e);
			throw new DataDaoException(e.getMessage(), e);
		}
		return list;
	}

	@Override
	public long count(String table, String ymd) throws DataDaoException {
		Connection con = null;
		Statement stmt = null;
		long count = 0;

		try {
			con = JdbcManager.getConnection(driverStr, urlStr, usernameStr, passwordStr);
			stmt = con.createStatement();
			ResultSet rs = null;

			try {
				rs = stmt.executeQuery("select count(*) as count from " + table + " where ymd='" + ymd + "'");
				while (rs.next()) {
					count = rs.getLong(1);
				}
			} catch (Exception e) {
				throw new Exception(e);
			} finally {
				if (rs != null)
					rs.close();
				stmt.close();
				con.close();
			}
		} catch (Exception e) {
			logger.error("RUN IMPALA SQL SHOW ERROR", e);
			throw new DataDaoException(e.getMessage(), e);
		}
		return count;
	}

	@Override
	public long refresh(String table) throws DataDaoException {
		Connection con = null;
		Statement stmt = null;
		long count = 0;
		try {
			con = JdbcManager.getConnection(Constant.IMPALA_DRIVER, Constant.IMPALA_CONNECTION, Constant.IMPALA_USER,
					Constant.IMPALA_PWD);
			stmt = con.createStatement();
			try {
				stmt.execute("refresh dw." + table);
			} catch (Exception e) {
				throw new Exception(e);
			} finally {
				stmt.close();
				con.close();
			}
		} catch (Exception e) {
			logger.error("RUN IMPALA SQL REFRESH", e);
			throw new DataDaoException(e.getMessage(), e);
		}
		return count;
	}

}